home *** CD-ROM | disk | FTP | other *** search
- /* :
- : 「compack.c」 ~ command pack utility ~
- : by Shinki.
- : 1991.11.09 1st version
- : ※ char = unsigned char
- */
-
- #include <string.h>
- #include <stdio.h>
- #include <stdlib.h>
- #include <memory.h>
- #include <ctype.h>
-
- #define LIST 0
- #define DELETE 1
- #define ADD 2
- #define RENAME 3
-
- /*
- #define debug
- */
- #define LEN 602
- #define MAX_LEN 0x5fff /* 最大ベースファイル長 */
-
- extern char basefile[LEN];
-
- char base_id[]=
- { 0xeb,0x35,0x43,0x4f,0x4d,0x50,0x41,0x43,0x4b };
-
- void main( int argc,char *argv[] );
- void help( void );
- void job( char *file1,char *file2,int mode );
- size_t GetFileLength( char *name );
- void error( char *msg1,char *msg2 );
-
- void main( int argc,char *argv[] )
- { char *s;
- int mode;
- char file1[128],file2[128];
- int i,n;
-
- /* 変数初期化 */
- mode=ADD;
- strcpy( file1,"" );
- strcpy( file2,"" );
-
- for( i=1;i<argc;i++ )
- { s=argv[i];
- if( *s=='-' || *s=='/' || *s=='^' )
- { switch( *(++s) )
- {
- /* case 'd': case 'D':
- mode=DELETE;
- break;
- */ case 'L': case 'l':
- mode=LIST;
- break;
- case 'A': case 'a':
- mode=ADD;
- break;
- case 'H': case 'h': case '?': /* help */
- help(); /* and exit */
- default:
- printf( "@ オプション指定エラー!! ('%c')\n\n",*s );
- exit( 1 );
- }
- }
- }
-
- n=0;
- for( i=1;i<argc;i++ )
- { s=argv[i];
- if( *s=='-' || *s=='/' || *s=='^' )
- continue;
-
- if( (n++)==0 )
- { strcpy( file1,s );
- if( (s=strrchr( file1,'.' ))!=NULL )
- *s='\0';
- strcat( file1,".com" );
- }
- else
- { strcpy( file2,s );
- if( (s=strrchr( file2,'.' ))!=NULL )
- *s='\0';
- strcat( file2,".com" );
- if( mode!=LIST )
- job( file1,file2,mode ); /* add/delete モード時 */
- }
- }
- if( file1[0]!='\0' && file2[0]=='\0' )
- mode=LIST; /* ベースファイルのみ指定時は、LIST指定に */
- if( file1[0]=='\0' )
- help(); /* ベースファイル指定無き場合は、HELP & EXIT */
- if( mode==LIST )
- job( file1,"",mode ); /* LIST モード時 */
- }
-
- size_t GetFileLength( char *name ) /* ==0.....errror */
- { FILE *fd;
- size_t len;
-
- if ( (fd=fopen( name,"rb" ))==NULL )
- return( 0 );
- fseek( fd,0,SEEK_END );
- len=(size_t)ftell( fd );
- if ( fclose( fd )==EOF )
- error( "file close","get_file_length" );
- return( len );
- }
-
- void error( char *msg1,char *msg2 )
- { printf( "@System error : '%s' in function:「%s」\n",msg1,msg2 );
- printf( "program aborted!!\n\n" );
- exit( 2 );
- }
-
- void help( void )
- { printf( "☆☆☆ Help Message for ComPack v1.00 By Shinki. ☆☆☆\n"
- "\n ComPack : 小さいCOMファイルをひとまとめにする\n"
- " 書式 : ComPack [-/Option] ベースファイル [ターゲットファイル1"
- " [ターゲット2 ・・・・]]\n" );
- printf( " Option : '?' or 'H' .... ヘルプメッセージ表示(この画面)\n"
- " : 'a' .... ベースファイルにターゲットファイルを"
- "しまい込む\n" );
- printf( " : 'l' .... ベースファイルの中身を調べる\n" );
- /*
- " : 'd' .... ベースファイルからターゲットファイル"
- "を削除する\n\n" );
- */
- printf( " Ex. : compack all prog1 ... all.com に prog1 を追加\n" );
- printf( " : compack all ... all.com の中身を閲覧\n\n" );
- exit( 0 );
- }
-
- void job( char *file1,char *file2,int mode )
- { FILE *fp1;
- size_t len1,len2;
- char buff[MAX_LEN];
- char temp[128]; /* 追加モジュール名認知用 */
- unsigned int pointer;
- char *s;
- char c;
- unsigned int address;
- unsigned int write_size; /* 書き込みサイズ */
- int nn,n; /* 連結プログラム数 */
- int i; /* ループカウンタ */
-
- len1=GetFileLength( file1 );
-
- if( len1>MAX_LEN ) /* 大きすぎた場合 */
- { printf( "@ これ以上プログラムを追加できません\n" );
- goto end;
- }
- if( len1==0 )
- { memcpy( buff,basefile,LEN ); /* 新規作成時 */
- len1=LEN;
- }
- else
- { if( (fp1=fopen( file1,"rb" ))==NULL )
- error( "file open","job" );
- if( fread( buff,1,(size_t)len1,fp1 )<len1 )
- error( "file read","job" );
- if( fclose( fp1 )==EOF )
- error( "file close","job" );
- for( i=0;i<8;i++ ) /* ベースファイルのIDチェック */
- { if( base_id[i]!=buff[i] )
- { printf( "@ ベースファイルが異常です\n" );
- exit( 1 );
- }
- }
- }
-
- pointer=(buff[10]-1)*256+buff[9]; /* header位置へリストア */
- nn=n=buff[pointer];
-
- #ifdef debug
- printf( "ヘッダ位置.......0x%04X\n",pointer );
- printf( "連結プログラム数......%d\n",n );
- printf( "buff[ 9].......%d\n",buff[9] );
- printf( "buff[10].......%d\n",buff[10] );
- #endif
-
- switch( mode )
- { case ADD:
- printf( "「%s」に「%s」を追加します\n",file1,file2 );
- if( (len2=GetFileLength( file2 ))==0 )
- { printf( "\x07 \x1b[31mファイルが見つかりません\x1b[m\n"
- ,file2 );
- goto end;
- }
-
-
- #ifdef debug
- printf( "length1.....%d / length2.....%d\n",len1,len2 );
- #endif
-
- if( (write_size=len1+len2+0x10)>=MAX_LEN )
- { printf( "\x07 \x1b[31mこれ以上追加できません\x1b[m\n" );
- goto end;
- }
-
- buff[pointer++]++; /* 連結プログラム数 インクリメント */
-
- while( (n--)>0 )
- { address=buff[pointer+10]+buff[pointer+11]*256+0x10;
- buff[pointer+10]=address%256;
- buff[pointer+11]=address/256; /* 格納位置をヘッダ分プラス */
- pointer+=0x10; /* ヘッダのスキップ */
- }
-
- #ifdef debug
- printf( "(len1-pointer)=%d\n",len1-pointer );
- #endif
-
- if( nn!=0 )
- memmove( &buff[pointer+0x10],&buff[pointer],
- (size_t)(len1-pointer) );
-
- strcpy( temp,file2 );
- if( (s=strrchr( temp,'.' ))!=NULL )
- *s='\0';
- if( (s=strrchr( temp,'\\' ))==NULL )
- s=temp;
- if( *s=='\\' )
- s++;
- if( *(s+1)==':' )
- s+=2;
- sprintf( &buff[pointer],"%-8s",s ); /* s:モジュール名 */
- for( i=1;i<=8;i++ )
- { c=buff[pointer]; /* モジュール名記入終了 */
- buff[pointer++]=toupper( c ); /* (オオモジ カ ) */
- }
- #ifdef debug
- printf( "write_size ......%d\n",write_size );
- printf( "モジュール名 : '%-8s'\n",s );
- #endif
-
- buff[pointer++]=len2%256;
- buff[pointer++]=len2/256; /* モジュールサイズ記入 */
-
- address=len1+0x110; /* address:追記プログラム格納位置 */
- buff[pointer++]=address%256;
- buff[pointer++]=address/256; /* 格納位置の記入終了 */
-
- buff[pointer++]=buff[pointer++]=buff[pointer++]=buff[pointer]=0;
- /* 予約領域をゼロクリア */
-
- pointer=len1+0x10; /* 追加位置へ移動 */
-
-
-
- if( (fp1=fopen( file2,"rb" ))==NULL )
- printf( "file open(file2)","job" );
- if( fread( &buff[pointer],1,(size_t)len2,fp1 )<len2 )
- error( "file read","job" );
- if( fclose( fp1 )==EOF )
- error( "file close(file2)","job" );
- /* 追加モジュール読み込み終了 */
-
- if( (fp1=fopen( file1,"wb" ))==NULL )
- error( "file open(basefile-write)","job" );
-
- if( fwrite( buff,1,write_size,fp1 )<write_size )
- error( "file write(basefile-write)","job" );
- if( fclose( fp1 )==EOF )
- error( "file close(basefile-write)","job" );
- break;
- case LIST:
- printf( "ベースファイル 「%s」 の一覧\n\n",file1 );
- if( n==0 )
- { printf( "@ ベースファイルが見つかりません\n" );
- exit( 1 );
- }
- pointer++;
- printf( " コマンド名 サイズ\n"
- "--------------- -----------\n"
- "ComPack本体 $%04x\n",pointer );
- for( ;n>0;n-- )
- { for( i=1;i<=8;i++ )
- putchar( buff[pointer++] );
- len2=buff[pointer++]+buff[pointer]*256;
- printf( " $%04x\n",len2 );
- pointer+=7; /* 予約領域スキップ */
- }
- printf( "--------------- -----------\n"
- " 合計 $%04x (残り $%04x バイト)\n"
- ,len1,MAX_LEN-len1 );
- break;
- }
- end:;
- }
-